package site.zhangzhuo.v1;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

//心
public class Xin implements Serializable {
    @Serial
    private static final long serialVersionUID= 3L;

    private final HashMap<String,Fa> wanfa=new HashMap<>();

    //空的心初始化，不从反序列化加载
    public void emptyInit(){
        System.out.println("----Xin emptyInit--------");
        addFas("法");
        addFasShu("法","心","色","声","香","味","触");
        addFasShu("色","红","黄","黑","白","灰",
                "明","暗");
        addFasShu("声","响","静");
        addFasShu("香","香","臭");
        addFasShu("味","酸","甜","苦","辣");
        addFasShu("触","粗","细","涩","滑","冷","热");
        addFasShu("法","空","有","无","虚","实","通","塞","大","小",
                "男","女","是","非","人","我");
        System.out.println(this);
    }
    //心的大小，法的数量
    public int size(){
        return wanfa.size();
    }
    //添加一个法
    public void addFa(Fa fa){
        wanfa.putIfAbsent(fa.getMing(),fa);
    }
    //添加多个法
    public void addFas(String... fas){
        for(String arg:fas){
            //wanfa中无才添加，否则会覆盖，对象发生变化。
            wanfa.putIfAbsent(arg,new Fa(arg));
        }
    }
    //添加从六根获得的法HashMap
    public void addFas(Yan yan){
        addFas(yan.toString());
    }
    //添加多个法fas及这些法的共同所属法shu
    public void addFasShu(String shu,String... fas){
        Fa suoshu=wanfa.get(shu);
        for(String arg:fas){
            Fa newfa=new Fa(arg);
            newfa.addShu(suoshu);
            wanfa.putIfAbsent(arg,newfa);
        }
    }
    /*
    提问，通过自扫描提问来填充连接
    如：扫描到某法对法为空则询问对法，获得答案后保存
    type限制问题类型
    number限制问题数量
    */
    public void questions(Relation type,int number){
        //用来对已回答的问题计数
        int count=0;
        //不能在遍历的过程中添加元素，所以需要添加的元素先放临时表中再合并
        HashMap<String,Fa> tmpFas=new HashMap<>();
        //临时把这两个法的名字存储起来
        HashMap<String,String> tMings=new HashMap<>();
        Scanner scanner=new Scanner(System.in);
        String str;
        //遍历wanfa寻找type关系HashMap为空的法
        for(Fa f:wanfa.values()){
            if(f.isEmpty(type)){
                if(count>=number)break;
                //打印输入法名交互提示：
                questionsPrint(f.getMing(),type);
                str=scanner.nextLine();
                //输入为空，跳过
                if(str.isBlank())continue;
                //输入不为空则尝试获取wanfa中此法
                Fa tfa=wanfa.get(str);
                //wanfa中有此法
                if(null!=tfa){
                    f.addRelationFa(type,tfa);
                }else{
                    //wanfa中无此法则new一个此法并放入临时HashMap等扫描完了再添加进去
                    tmpFas.put(str,new Fa(str));
                    //同时记下两个法的名字后续添加关系的时候使用
                    tMings.put(f.getMing(),str);
                }
                count++;
            }
        }
        //先把新法添加进wanfa
        wanfa.putAll(tmpFas);
        //再设置新法的关系
        for(String str2:tMings.keySet()){
            setRelation(type,str2,tMings.get(str2));
        }
        scanner.close();
    }
    private void questionsPrint(String ming,Relation type){
        switch (type){
            case DUI:
                System.out.println(ming+"的对法为：");
                break;
            case SHU:
                System.out.println(ming+"的所属法为：");
                break;
        }
    }
    //设置两个法的关系，前提是这两个法都在wanfa中
    private void setRelation(Relation type,String fa1,String suo){
        switch (type){
            case DUI:
                wanfa.get(fa1).addDui(wanfa.get(suo));
                wanfa.get(suo).addDui(wanfa.get(fa1));
                break;
            case SHU:
                wanfa.get(fa1).addShu(wanfa.get(suo));
                break;
        }
    }

    //提问，通过自扫描提问来填充连接
    //如：扫描到某法对法为空则询问对法，获得答案后保存
    //number限制问题数量
    @Deprecated
    public void questionDui(int number){
        //用来对已回答的问题计数
        int count=0;
        //不能在遍历的过程中添加元素，所以需要添加的元素先放临时表中再合并
        HashMap<String,Fa> tfas=new HashMap<>();
        HashMap<String,String> tdui=new HashMap<>();
        Scanner scanner=new Scanner(System.in);
        String str;
        for(Fa f:wanfa.values()){
            if(f.isEmptyDui()){
                if(count>=number)break;
                System.out.println(f.getMing()+"的对法为：");
                str=scanner.nextLine();
                if(str.isBlank())continue;
                Fa tfa=wanfa.get(str);
                if(null!=tfa){
                    f.addDui(tfa);
                }else{
                    tfas.put(str,new Fa(str));
                }
                tdui.put(f.getMing(),str);
                count++;
            }
        }
        wanfa.putAll(tfas);
        for(String str2:tdui.keySet()){
            setRelation(Relation.DUI,str2,tdui.get(str2));
        }
        scanner.close();
    }
    //从文件反序列化载入
    public static Xin load(String filename) {
        System.out.println("------reSerialized read Xin---------" + filename);
        try {
            FileInputStream fileIn = new FileInputStream(filename);
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Xin xin = (Xin) in.readObject();
            in.close();
            fileIn.close();
            return xin;
        } catch (IOException i) {
            i.printStackTrace();
        } catch (ClassNotFoundException c) {
            System.out.println("class not found");
            c.printStackTrace();
        }
        return null;
    }
    //序列化到文件
    public void save(String filename){
        System.out.println("------Serialized save Xin---------"+filename);
        try
        {
            FileOutputStream fileOut = new FileOutputStream(filename);
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(this);
            out.close();
            fileOut.close();
        }catch(IOException i)
        {
            i.printStackTrace();
        }
    }
    @Override
    public String toString(){
        StringBuilder str=new StringBuilder();
        for(Map.Entry<String,Fa> fa:wanfa.entrySet()){
            if(!fa.getKey().isBlank()) str.append(fa.getValue());
            else if (fa.getKey().equals("\n")) str.append("换行\\n");
            else if(fa.getKey().equals(" ")) str.append("空格 ");
        }
        return new String(str);
    }
}
